/*******************************************************************************
 * Copyright (c) 2010 Marcelo Cataldo, Sangeeth Nambiar
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * JungGraph.java
 * 
 * The graph model compatible to the viewer library from JUNG
 * 
 * Contributors:
 *    Marcelo Cataldo  - initial implementation 
 *    Sangeeth Nambiar - initial implementation
 *******************************************************************************/
package edu.cmu.isr.dinvenio.ui.graphViewer;

import java.awt.Paint;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;

import edu.cmu.isr.dinvenio.model.DepsGraph;
import edu.cmu.isr.dinvenio.model.DepsGraphEdge;
import edu.cmu.isr.dinvenio.model.DepsGraphLayer;
import edu.cmu.isr.dinvenio.model.DepsGraphNode;

import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseMultigraph;
import edu.uci.ics.jung.graph.util.EdgeType;

public class JungGraph {
	
	private DepsGraph depsGraphModel;
	
	// JUNG Objects
	public Graph<DepsGraphNode,DepsGraphEdge> graph;
	public Hashtable<String,DepsGraphNode> jungGraphNodes;
	public ArrayList<DepsGraphEdge> graphEdges;
	private JungViewer jungViewer;
	
	public JungGraph(DepsGraph graph) {
		this.depsGraphModel = graph;
		this.graph          = new SparseMultigraph<DepsGraphNode,DepsGraphEdge>();
		this.jungGraphNodes = new Hashtable<String,DepsGraphNode>();
		this.graphEdges     = new ArrayList<DepsGraphEdge>();
	}

	public void transtlateDepsGraphToJung(){		
		// iterate on the graph layers
		Enumeration<DepsGraphLayer> llist = depsGraphModel.layers.elements();
		while(llist.hasMoreElements()) {
			DepsGraphLayer l = llist.nextElement();
			if(l.getEnableStatus()){				
				// Migrate all edges
				for(int i = 0; i < l.getEdges().size(); i++) {
					DepsGraphEdge edge = l.getEdges().get(i);					
					DepsGraphNode s = l.getSourceNodeByName(edge.source); 
					DepsGraphNode d = l.getTargetNodeByName(edge.target);
					if ((edge != null) && (s != null)&& (d != null)) {
						if (!jungGraphNodes.containsKey(edge.source)) {
							this.graph.addVertex(s);
							jungGraphNodes.put(s.getId(), s);
						}
						if (!jungGraphNodes.containsKey(edge.target)) {
							this.graph.addVertex(d);
							jungGraphNodes.put(d.getId(), d);
						}
						this.graph.addEdge(edge, s,d,EdgeType.DIRECTED);
						graphEdges.add(edge);
						jungViewer.putEdgeColorInMap(edge);
					}
				}
			}
		}
	}
	
	public void clearGraph() {
	    // Remove all nodes
		Collection<DepsGraphNode> Nodes = jungGraphNodes.values();
		for (DepsGraphNode n : Nodes){
			this.graph.removeVertex(n);
		}
		this.jungGraphNodes = new Hashtable<String,DepsGraphNode>();
		
		// Remove all edges
		Iterator<DepsGraphEdge> itr = graphEdges.iterator();
		while(itr.hasNext()){
			this.graph.removeEdge(itr.next());
		}
		this.graphEdges = new ArrayList<DepsGraphEdge>();
		jungViewer.refresh();
	}

	public String getPropertyForNodeColor() {
		return depsGraphModel.getPropertyForNodeColor();
	}

	public double getNodeColorMax() {
		return depsGraphModel.getNodeColorMax();
	}

	public double getNodeColorMin() {
		return depsGraphModel.getNodeColorMin();
	}

	public void setViewer(JungViewer jV) {
		this.jungViewer = jV;
		
	}

	public void setLayerVisibility(String l, boolean vis) {
		depsGraphModel.getLayer(l).setVisibility(vis);
		ArrayList<DepsGraphEdge> es = depsGraphModel.getLayer(l).getEdges();
		for (DepsGraphEdge e : es) {
			jungViewer.putEdgeColorInMap(e);
		}
		jungViewer.refresh();		
	}

	public void disableLayer(String lid) {
		depsGraphModel.disableLayer(lid);		
	}

	public void enableLayer(String lid) {
		depsGraphModel.enableLayer(lid);		
	}

	public Paint getColorFromTable(String pv) {
		return depsGraphModel.getColorFromTable(pv);
	}

	public String getPropertyForNodeSize() {
		return depsGraphModel.getPropertyForNodeSize();
	}

	public double getNodeSizeMax() {
		return depsGraphModel.getNodeSizeMax();
	}

	public double getNodeSizeMin() {
		return depsGraphModel.getNodeSizeMin();
	}

	public int getNumEdges() {
		return graphEdges.size();
	}

}
